package com.yeziji.devops.constant.mysql;

import cn.hutool.core.util.StrUtil;
import com.yeziji.common.CommonEnum;
import com.yeziji.common.CommonSymbol;
import lombok.Getter;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.StringJoiner;

/**
 * Mysql 关键字枚举
 *
 * @author hwy
 * @since 2024/07/18 0:44
 **/
@Getter
public enum MysqlKeywordEnum implements CommonEnum {
    FROM(0, "FROM", "指定的数据表名关键字"),
    ALL_COLUMNS(1, "*", "查询所有字段"),
    WHERE(2, "WHERE", "查询条件起始符"),
    END(3, ";", "终止符"),
    COUNT(4, "COUNT(1)", "统计数量，默认为 1"),
    /**
     * into 关键字
     */
    INTO(5, "INTO", "插入指定的表关键字"),
    /**
     * values 关键字
     */
    VALUES(6, "VALUES", "插入值时使用的关键字"),
    /**
     * set 关键字
     */
    SET(7, "SET", "更新操作时 update table set 关键字"),
    /**
     * table 关键字
     */
    TABLE(8, "TABLE", "table 关键字，一般用于删除、创建数据表"),
    /**
     * database 关键字
     */
    DATABASE(9, "DATABASE", "database 关键字，一般用于删除、创建数据库"),
    /**
     * drop 关键字
     */
    DROP(10, "DROP", "drop 关键字用于删除 table"),
    /**
     * if 关键字
     */
    IF(11, "IF", "if 关键字"),
    /**
     * exists 关键字
     */
    EXISTS(12, "EXISTS", "判断是否存在"),
    VARCHAR(13, "VARCHAR", "字符串类型"),
    LONGTEXT(14, "LONGTEXT", "字符串类型"),
    CHAR(15, "CHAR", "字符串类型"),
    TEXT(16, "TEXT", "字符串类型"),
    BLOB(17, "BLOB", "字符串类型"),
    ENUM(18, "ENUM", "字符串类型"),
    CHARACTER(19, "CHARACTER", "编码类型关键字"),
    COLLATE(20, "COLLATE", "字段排序方式"),
    NULL(21, "NULL", "空"),
    NOT_NULL(22, "NOT NULL", "非空"),
    DEFAULT(23, "DEFAULT", "默认值"),
    COMMENT(24, "COMMENT", "备注"),
    PRIMARY(25, "PRIMARY", "主键关键字"),
    KEY(26, "KEY", "KEY 关键字"),
    USING(27, "USING", "USING 关键字"),
    BTREE(28, "BTREE", "索引方式 BTREE - USING BTREE"),
    HASH(29, "HASH", "索引方式 HASH - USING HASH"),
    AUTO_INCREMENT(30, "AUTO_INCREMENT", "自增"),
    INDEX(31, "INDEX", "索引关键字"),
    CONSTRAINT(32, "CONSTRAINT", "CONSTRAINT 外键定义关键字"),
    FOREIGN_KEY(33, "FOREIGN KEY", "FOREIGN KEY 指定外键"),
    REFERENCES(34, "REFERENCES", "REFERENCES 关键字"),
    ON(35, "ON", "ON 关键字"),
    DELETE(36, "DELETE", "DELETE 关键字"),
    UPDATE(37, "UPDATE", "UPDATE 关键字"),
    ENGINE(38, "ENGINE", "ENGINE 关键字"),
    INNODB(39, "InnoDB", "InnoDB 数据库引擎"),
    ROW_FORMAT(40, "ROW_FORMAT", "行格式"),
    CURRENT_TIMESTAMP(41, "CURRENT_TIMESTAMP", "获取当前时间戳"),
    AND(42, "AND", "AND 关键字"),
    IN(43, "IN", "IN 关键字"),
    LEFT_OUTER_JOIN(44, "LEFT OUTER JOIN", "LEFT_OUTER_JOIN 关键字"),
    LEFT_JOIN(45, "LEFT JOIN", "LEFT JOIN 关键字"),
    ALTER(46, "ALTER", "ALTER 修改关键字"),
    ADD(47, "ADD", "追加 ADD 关键字"),
    COLUMN(48, "COLUMN", "column 关键字"),
    MODIFY(49, "MODIFY", "modify 修改关键字"),
    CHANGE(50, "CHANGE", "CHANGE 更改关键字"),
    RENAME(51, "RENAME", "RENAME 关键字，主要操作表名更改"),
    TO(52, "TO", "TO 关键字"),
    CHARSET(53, "CHARSET", "CHARSET 表字符集关键字"),
    FIELDS_TYPE_PRIMARY_KEY(54, "PRI", "数据库中代表字段主键的 key 名称"),
    FIELDS_TYPE_UNIQUE_KEY(55, "UNI", "数据库中代表字段唯一的 key 名称"),
    RTREE(56, "RTREE", "索引方式 RTREE - USING RTREE"),
    FULL_TEXT(57, "FULLTEXT", "索引方式 FULL TEXT - CREATE FULL TEXT INDEX"),
    USE(58, "USE", "使用 xxx"),
    ;

    private final int code;
    private final String value;
    private final String desc;
    private StringJoiner spaceJoiner = new StringJoiner(CommonSymbol.SPACE);

    private boolean appendFlag;
    MysqlKeywordEnum(int code, String value, String desc) {
        this.code = code;
        this.value = value;
        this.desc = desc;
    }

    /**
     * 追加拼接空格字符串
     *
     * @param value 拼接字符串
     * @return {@link StringJoiner} 支持继续拼接
     */
    public MysqlKeywordEnum append(String value) {
        if (!this.appendFlag) {
            this.spaceJoiner.add(this.value);
            this.appendFlag = true;
        }
        this.spaceJoiner.add(value);
        return this;
    }

    /**
     * 获取 space joiner 的拼接结果
     *
     * @return {@link String}
     */
    public String toStr() {
        String str = this.spaceJoiner.toString() + ";";
        // clear
        this.spaceJoiner = new StringJoiner(CommonSymbol.SPACE);
        this.appendFlag = false;
        return str;
    }

    /**
     * 判断是否可以当作字符串类型的编码
     *
     * @param key 判断编码字符串
     * @return {@link Boolean}
     */
    public static boolean isStrCharacter(String key) {
        List<String> strTypes =
                Arrays.asList("CHAR", "VARCHAR", "BINARY", "BLOB", "TEXT", "LONGTEXT", "ENUM", "SET");
        return strTypes.contains(key.toUpperCase());
    }

    /**
     * 判断 keyword 是否相等
     *
     * @param v1          判断值
     * @param keywordEnum 对比枚举
     * @return {@link Boolean}
     */
    public static boolean keywordEquals(String v1, MysqlKeywordEnum keywordEnum) {
        if (StrUtil.isBlank(v1)) {
            return false;
        }
        return v1.toUpperCase().equals(keywordEnum.getValue());
    }

    /**
     * 括号住多个属性
     *
     * @param values 属性值
     * @return {@link String}
     */
    public static String brackets(Collection<?> values) {
        return brackets(values, false);
    }

    /**
     * 引用值
     *
     * @param value 引用字符串
     * @return {@link String}
     */
    public static String quoteVal(String value) {
        return "`" + value + "`";
    }

    /**
     * 單引用值
     *
     * @param value 引用字符串
     * @return {@link String}
     */
    public static String singeQuoteVal(String value) {
        return "'" + value + "'";
    }

    /**
     * 引用值
     *
     * @param value          引用值
     * @param isReverseQuote 是否反引号
     * @return {@link String}
     */
    public static String bracket(Object value, boolean isReverseQuote) {
        if (isReverseQuote) {
            return "(`" + value + "`)";
        }
        return "(" + value + ")";
    }

    /**
     * 拼接括号字符
     *
     * @param value 待拼接参数
     * @return {@link String}
     */
    public static String bracket(Object value) {
        return bracket(value, false);
    }

    /**
     * 拼接括号字符
     *
     * @param values         多个 values
     * @param isReverseQuote 是否反引号
     * @return {@link String}
     */
    public static String brackets(Collection<?> values, boolean isReverseQuote) {
        StringJoiner sj = new StringJoiner(", ", "(", ")");
        for (Object value : values) {
            if (isReverseQuote) {
                sj.add("`" + value + "`");
            } else {
                if (value instanceof String) {
                    sj.add("'" + value + "'");
                } else {
                    sj.add(String.valueOf(value));
                }
            }
        }
        return sj.toString();
    }

    /**
     * 生成符合 MySql 的 value（如果是字符串追加单引号）
     *
     * @param value value 值
     * @return {@link String}
     */
    public static String value(Object value) {
        if (value instanceof String) {
            return "'" + value + "'";
        }
        return String.valueOf(value);
    }

    /**
     * 生成符合 MySql 的 eq wrapper
     *
     * @param key   key
     * @param value value
     * @return {@link String} key=value | key='value'
     */
    public static String wrapper(String key, Object value) {
        if (value instanceof String) {
            return key + "=" + "'" + value + "'";
        }
        return key + "=" + value;
    }

    /**
     * 生成关键字 equals wrapper
     *
     * @param key 关键字
     * @param val 等于值
     * @return {@link String} key=value
     */
    public static String editKeyword(MysqlKeywordEnum key, Object val) {
        return key.getValue() + "=" + val;
    }

    /**
     * count 关键字
     *
     * @param column 对应的 column
     * @return {@link String} count(column)
     */
    public static String count(String column) {
        return "count(" + column + ")";
    }

    /**
     * 别名
     *
     * @param val   值
     * @param alias 别名
     * @return {@link String} val AS alias
     */
    public static String alias(String val, String alias) {
        return val + " AS " + alias;
    }

    /**
     * 是否允许为 null
     *
     * @param accept 是否允许
     * @return {@link String} NULL | NOT NULL
     */
    public static String acceptNull(Boolean accept) {
        if (accept != null) {
            return accept ? MysqlKeywordEnum.NULL.getValue() : MysqlKeywordEnum.NOT_NULL.getValue();
        }
        return null;
    }

    /**
     * comment 关键字
     *
     * @param msg comment 值
     * @return {@link String} COMMENT 'ABC'
     */
    public static String comment(String msg) {
        return MysqlKeywordEnum.COMMENT.getValue() + " '" + msg + "'";
    }

    /**
     * 根据 value 获取枚举值
     *
     * @param value 对应的 value
     * @return {@link MysqlKeywordEnum}
     */
    public static MysqlKeywordEnum getByValue(String value) {
        if (value == null) {
            return null;
        }
        for (MysqlKeywordEnum MysqlKeywordEnum : MysqlKeywordEnum.values()) {
            if (MysqlKeywordEnum.getValue().equals(value.toUpperCase())) {
                return MysqlKeywordEnum;
            }
        }
        return null;
    }
}
